using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc.Controllers;
using zhwy.saas.api.Models;
using System.Text.Json;
using zhwy.saas.api.Services.Sinterface;


namespace zhwy.saas.api.Middleware
{
    public class JwtAuthenticationMiddleware
    {
        private readonly RequestDelegate _next;
        private readonly ITokenService _tokenService;

        public JwtAuthenticationMiddleware(
            RequestDelegate next,
            ITokenService tokenService)
        {
            _next = next;
            _tokenService = tokenService;
        }

        public async Task InvokeAsync(HttpContext context)
        {
            // 检查是否需要跳过验证
            if (ShouldSkipAuth(context))
            {
                await _next(context);
                return;
            }

            var token = context.Request.Headers["Authorization"].FirstOrDefault()?.Split(" ").Last();

            if (string.IsNullOrEmpty(token))
            {
                await HandleUnauthorizedAsync(context, "未提供Token");
                return;
            }

            var principal = _tokenService.ValidateToken(token);
            if (principal == null)
            {
                await HandleUnauthorizedAsync(context, "Token无效或已过期");
                return;
            }

            context.User = principal;
            await _next(context);
        }

        private bool ShouldSkipAuth(HttpContext context)
        {
            // 1. 检查固定的跳过路径
            var skipPaths = new[]
            {
                "/swagger",
                "/health"
            };

            if (skipPaths.Any(p => context.Request.Path.StartsWithSegments(p, StringComparison.OrdinalIgnoreCase)))
            {
                return true;
            }

            // 2. 检查 AllowAnonymous 特性
            var endpoint = context.GetEndpoint();
            if (endpoint == null)
            {
                return false;
            }

            // 检查控制器或action是否标记了 AllowAnonymous
            var allowAnonymous = endpoint.Metadata.GetMetadata<AllowAnonymousAttribute>();
            if (allowAnonymous != null)
            {
                return true;
            }

            // 3. 检查是否是登录接口
            if (endpoint.Metadata.GetMetadata<ControllerActionDescriptor>() is ControllerActionDescriptor actionDescriptor)
            {
                if (actionDescriptor.ControllerName.Equals("Auth", StringComparison.OrdinalIgnoreCase) &&
                    actionDescriptor.ActionName.Equals("Login", StringComparison.OrdinalIgnoreCase))
                {
                    return true;
                }
            }

            return false;
        }

        private async Task HandleUnauthorizedAsync(HttpContext context, string message)
        {
            context.Response.ContentType = "application/json";
            context.Response.StatusCode = StatusCodes.Status401Unauthorized;

            var response = new ApiResponseModel<object>()
            {
                Success = false,
                Code = StatusCodes.Status401Unauthorized,  // 对外显示友好的错误信息
                Message = message,
                Data = null
            };

            await context.Response.WriteAsync(JsonSerializer.Serialize(response));
        }
    }
} 